<template>
  <div id="addNotePage">
    <h2 style="margin-bottom: 16px">
      {{ route.query?.id ? '修改笔记' : '创建笔记' }}
    </h2>
    <a-form v-if="note" layout="vertical" :model="noteForm" @finish="handleSubmit">
      <!-- 标题 -->
      <a-form-item label="标题" name="title" required>
        <a-input v-model:value="noteForm.title" placeholder="请输入标题" />
      </a-form-item>

      <!-- 封面上传 -->
      <a-form-item label="封面图片（可选）">
        <a-upload
          v-model:file-list="fileList"
          name="file"
          :customRequest="handleUpload"
          :show-upload-list="false"
          accept="image/*"
        >
          <a-button>
            <upload-outlined></upload-outlined>
            选择封面
          </a-button>
        </a-upload>
      </a-form-item>

      <!-- 封面预览 -->
      <div v-if="noteForm.cover" class="cover-preview" :class="{ 'show-cover': noteForm.cover }">
        <div class="image-container">
          <img :src="noteForm.cover" alt="封面预览" />
          <a-button type="primary" danger class="remove-btn" @click="removeCover">
            移除封面
          </a-button>
        </div>
      </div>

      <!-- Markdown 编辑器 -->
      <a-form-item label="笔记内容" required>
        <div class="editor-container">
          <div class="theme-selector">
            <span>选择主题：</span>
            <a-select v-model:value="currentTheme" style="width: 200px" @change="handleThemeChange">
              <a-select-option v-for="theme in themeList" :key="theme.name" :value="theme.name">
                {{ theme.name }}
              </a-select-option>
            </a-select>
          </div>
          <Editor
            :value="noteForm.content"
            :locale="zhHans"
            @change="(v: string) => (noteForm.content = v)"
            :plugins="plugins"
            :uploadImages="uploadImages"
          />
        </div>
      </a-form-item>

      <!-- 分类选择 -->
      <a-form-item label="分类" required>
        <a-select
          v-model:value="noteForm.categoryId"
          placeholder="请选择分类"
          style="width: 100%"
          allowClear
        >
          <a-select-option v-for="category in categoryList" :key="category.id" :value="category.id">
            {{ category.categoryName }}
          </a-select-option>
        </a-select>
      </a-form-item>

      <!-- 可见性选择 -->
      <a-form-item label="可见性" required>
        <a-radio-group v-model:value="noteForm.visibility" :default-value="1">
          <a-radio :value="1">公开</a-radio>
          <a-radio :value="0">仅自己可见</a-radio>
        </a-radio-group>
      </a-form-item>

      <!-- 标签展示区 -->
      <a-form-item label="标签" required>
        <div class="tags-container">
          <a-space wrap>
            <a-tag
              v-for="tag in selectedTags"
              :key="tag.id"
              closable
              @close="removeTag(tag)"
              style="margin-bottom: 7px"
            >
              {{ tag.tagName }}
            </a-tag>
          </a-space>
          <a-button type="dashed" @click="showTagsModal">
            <plus-outlined />
            添加标签
          </a-button>
        </div>
      </a-form-item>

      <!-- 提交按钮 -->
      <a-form-item>
        <a-button type="primary" html-type="submit" style="width: 100%">
          {{ route.query?.id ? '保存修改' : '创建笔记' }}
        </a-button>
      </a-form-item>
    </a-form>

    <!-- 标签选择弹窗 -->
    <a-modal
      v-model:visible="tagsModalVisible"
      title="选择标签"
      @ok="handleTagsConfirm"
      width="600px"
    >
      <div class="tags-modal-content">
        <div class="modal-header">
          <a-flex justify="space-between" align="center">
            <div class="title">选择标签</div>
            <a-button type="primary" @click="showAddTagModal">
              <plus-outlined />
              添加新标签
            </a-button>
          </a-flex>
        </div>

        <div class="tags-section" style="margin: 15px 0">
          <div class="section-title">系统标签</div>
          <div class="tags-list">
            <a-checkable-tag
              v-for="tag in systemTags"
              :key="tag.id"
              :checked="isTagSelected(tag)"
              @change="(checked) => handleTagSelect(tag, checked)"
              class="tag-item"
              style="margin: 10px 10px; border: 1px solid #1890ff"
            >
              {{ tag.tagName }}
            </a-checkable-tag>
          </div>
        </div>

        <div class="tags-section" style="margin: 15px 0">
          <div class="section-title">自定义标签</div>
          <div class="tags-list">
            <a-checkable-tag
              v-for="tag in customTags"
              :key="tag.id"
              :checked="isTagSelected(tag)"
              @change="(checked) => handleTagSelect(tag, checked)"
              class="tag-item"
              style="margin: 10px 10px; border: 1px solid #1890ff"
            >
              {{ tag.tagName }}
            </a-checkable-tag>
          </div>
        </div>
      </div>
    </a-modal>

    <!-- 添加新标签弹窗 -->
    <a-modal
      v-model:visible="addTagModalVisible"
      title="添加新标签"
      @ok="handleAddTag"
      :confirmLoading="addingTag"
    >
      <a-input v-model:value="newTagName" placeholder="请输入标签名称" />
    </a-modal>
  </div>
</template>

<script setup lang="ts">
import { onMounted, reactive, ref, watch } from 'vue'
import { message } from 'ant-design-vue'
import { useRoute, useRouter } from 'vue-router'
import {
  addNoteUsingPost,
  editNoteUsingPost,
  getNoteVoByIdUsingGet,
  listNoteTagsCategoryUsingGet,
} from '@/api/notesController'
import { addTagsUsingPost, listMyTagsVoByPageUsingPost } from '@/api/tagsController'
import { uploadFileUsingPost } from '@/api/fileController'
import { Editor } from '@bytemd/vue-next'
import gfm from '@bytemd/plugin-gfm'
import highlight from '@bytemd/plugin-highlight'
import 'bytemd/dist/index.css'
import zhHans from 'bytemd/lib/locales/zh_Hans.json'
import { PlusOutlined, UploadOutlined } from '@ant-design/icons-vue'
import theme from 'bytemd-plugin-theme'
import { useLoginUserStore } from '@/stores/useLoginUserStore'
import { currentTheme, handleThemeChange, themeList } from '@/utils/themeManager'
import highlightssr from '@bytemd/plugin-highlight-ssr'
import breaks from '@bytemd/plugin-breaks'
import frontmatter from '@bytemd/plugin-frontmatter'
import footnotes from '@bytemd/plugin-footnotes'
import gemoji from '@bytemd/plugin-gemoji'
import mediumZoom from '@bytemd/plugin-medium-zoom'
// ByteMD 插件
const plugins = [
  gfm(),
  highlight(),
  highlightssr(),
  breaks(),
  frontmatter(),
  footnotes(),
  gemoji(),
  theme(),
  mediumZoom(),
]

// 监听主题变化
watch(currentTheme, (newTheme) => {
  handleThemeChange(newTheme)
})

// 初始化主题
onMounted(() => {
  handleThemeChange(currentTheme.value)
})

const loginUserStore = useLoginUserStore()

const route = useRoute()
const router = useRouter()

const note = ref<API.NotesVO>({})
const noteForm = reactive<API.NotesEditRequest>({
  content: '',
  title: '',
  categoryId: undefined,
  cover: '',
  visibility: 1, // 默认公开
})

// 文件上传相关
const fileList = ref([])
const handleUpload = async (options: any) => {
  const { file, onSuccess, onError } = options
  try {
    const formData = new FormData()
    formData.append('file', file)
    const res = await uploadFileUsingPost({ biz: 'note_cover' }, formData, file)
    if (res.data.code === 0) {
      noteForm.cover = res.data.data
      onSuccess()
    } else {
      onError()
      message.error('上传失败：' + res.data.message)
    }
  } catch (error) {
    onError()
    message.error('上传失败')
  }
}

const removeCover = () => {
  noteForm.cover = ''
  fileList.value = []
}

// 图片上传处理函数（用于编辑器）
const uploadImages = async (files: File[]) => {
  try {
    const promises = files.map(async (file) => {
      const formData = new FormData()
      formData.append('file', file)
      const res = await uploadFileUsingPost({ biz: 'note_attachment' }, formData, file)
      if (res.data.code === 0 && res.data.data) {
        return {
          url: res.data.data,
          title: file.name,
          alt: file.name,
        }
      } else {
        message.error('图片上传失败：' + res.data.message)
        return null
      }
    })

    const results = await Promise.all(promises)
    // 过滤掉上传失败的图片
    return results.filter((result) => result !== null)
  } catch (error) {
    message.error('图片上传失败')
    return []
  }
}

// 分类相关
const categoryList = ref<API.Categories[]>([])
const fetchCategories = async () => {
  const res = await listNoteTagsCategoryUsingGet()
  if (res.data.code === 0 && res.data.data) {
    categoryList.value = res.data.data.categoriesList ?? []
  }
}

// 标签相关
const selectedTags = ref<API.Tags[]>([])
const systemTags = ref<API.Tags[]>([])
const customTags = ref<API.Tags[]>([])
const tagsModalVisible = ref(false)
const addTagModalVisible = ref(false)
const newTagName = ref('')
const addingTag = ref(false)

const showTagsModal = async () => {
  // 打开弹窗前获取最新的标签数据
  await fetchTags()
  tagsModalVisible.value = true
}

const showAddTagModal = () => {
  newTagName.value = ''
  addTagModalVisible.value = true
}

const isTagSelected = (tag: API.Tags) => {
  return selectedTags.value.some((t) => t.id === tag.id)
}

const handleTagSelect = (tag: API.Tags, checked: boolean) => {
  if (checked) {
    selectedTags.value.push(tag)
  } else {
    selectedTags.value = selectedTags.value.filter((t) => t.id !== tag.id)
  }
}

const removeTag = (tag: API.Tags) => {
  selectedTags.value = selectedTags.value.filter((t) => t.id !== tag.id)
}

const handleTagsConfirm = () => {
  noteForm.tags = selectedTags.value
  tagsModalVisible.value = false
}

// 获取标签列表
const fetchTags = async () => {
  // 获取系统标签
  const res = await listNoteTagsCategoryUsingGet()
  if (res.data.code === 0 && res.data.data) {
    const tagsList = res.data.data.tagsList ?? []
    // 只获取系统标签（userId === '1'）
    systemTags.value = tagsList.filter((tag) => tag.userId === '1')
  }

  // 获取用户自定义标签
  const myTagsRes = await listMyTagsVoByPageUsingPost({
    pageSize: 15, // 设置较大的页面大小以获取所有标签
    current: 1,
    sortField: 'create_time',
    sortOrder: 'descend',
  })
  if (myTagsRes.data.code === 0 && myTagsRes.data.data) {
    customTags.value = myTagsRes.data.data.records ?? []
  }
}

const handleAddTag = async () => {
  if (!newTagName.value.trim()) {
    message.warning('请输入标签名称')
    return
  }

  addingTag.value = true
  try {
    const res = await addTagsUsingPost({
      tagName: newTagName.value.trim(),
      userId: loginUserStore.loginUser.id,
    })
    if (res.data.code === 0) {
      message.success('添加标签成功')
      addTagModalVisible.value = false
      // 刷新标签列表
      await fetchTags()
    } else {
      message.error('添加标签失败：' + res.data.message)
    }
  } finally {
    addingTag.value = false
  }
}

// 提交表单
const handleSubmit = async () => {
  if (!noteForm.title?.trim()) {
    message.warning('请输入标题')
    return
  }
  if (!noteForm.content?.trim()) {
    message.warning('请输入内容')
    return
  }
  if (!noteForm.categoryId) {
    message.warning('请选择分类')
    return
  }
  if (selectedTags.value.length === 0) {
    message.warning('请至少选择一个标签')
    return
  }

  try {
    const isEdit = !!route.query?.id
    const submitData = {
      ...noteForm,
      tags: selectedTags.value,
    }

    if (isEdit) {
      // 编辑模式
      const res = await editNoteUsingPost({
        ...submitData,
        id: route.query.id,
      })
      if (res.data.code === 0) {
        message.success('修改成功')
        router.push('/note/' + route.query.id)
      } else {
        message.error('修改失败：' + res.data.message)
      }
    } else {
      // 创建模式
      const res = await addNoteUsingPost({
        ...submitData,
        userId: loginUserStore.loginUser.id,
      })
      if (res.data.code === 0) {
        message.success('创建成功')
        router.push('/note/' + res.data.data)
      } else {
        message.error('创建失败：' + res.data.message)
      }
    }
  } catch (error: any) {
    message.error('操作失败：' + error.message)
  }
}

// 获取笔记详情（编辑模式）
const getOldNote = async () => {
  const id = route.query?.id
  if (!id) {
    return
  }
  const res = await getNoteVoByIdUsingGet({ id })
  if (res.data.code === 0 && res.data.data) {
    const data = res.data.data
    note.value = data
    noteForm.title = data.title
    noteForm.content = data.content
    noteForm.categoryId = data.categoryId
    noteForm.cover = data.cover
    noteForm.visibility = data.visibility ?? 1 // 设置可见性，默认公开
    selectedTags.value = data.tagList || []
    if (data.cover) {
      fileList.value = [
        {
          uid: '-1',
          name: 'cover',
          status: 'done',
          url: data.cover,
        },
      ]
    }
  }
}

// 获取分类和标签数据
const fetchCategoryAndTags = async () => {
  const res = await listNoteTagsCategoryUsingGet()
  if (res.data.code === 0 && res.data.data) {
    // 设置分类列表
    categoryList.value = res.data.data.categoriesList ?? []
    // 设置标签列表
    const tagsList = res.data.data.tagsList ?? []
    systemTags.value = tagsList.filter((tag) => tag.userId === '1')
    customTags.value = tagsList.filter((tag) => tag.userId === loginUserStore.loginUser.id)
  } else {
    message.error('获取分类和标签失败：' + res.data.message)
  }
}

onMounted(async () => {
  await Promise.all([fetchCategoryAndTags(), getOldNote()])
})
</script>

<style scoped>
#addNotePage {
  max-width: 1200px;
  margin: 0 auto;
  padding: 20px;

  .cover-preview {
    margin: 16px 0;
    opacity: 0;
    height: 0;
    transition: all 0.3s ease;
    overflow: hidden;

    &.show-cover {
      opacity: 1;
      height: 400px;
    }

    .image-container {
      position: relative;
      width: 100%;
      height: 100%;
      display: flex;
      justify-content: center;
      align-items: center;

      img {
        max-height: 360px;
        max-width: 100%;
        object-fit: contain;
        border-radius: 8px;
      }

      .remove-btn {
        position: absolute;
        bottom: 16px;
        right: 16px;
        border-radius: 4px;
      }
    }
  }

  .tags-container {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    align-items: center;
  }

  .tags-modal-content {
    .modal-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-bottom: 20px;
      padding-bottom: 16px;
      border-bottom: 1px solid #f0f0f0;

      .title {
        font-size: 16px;
        font-weight: 500;
        color: rgba(0, 0, 0, 0.85);
      }
    }

    .tags-section {
      margin-bottom: 24px;

      .section-title {
        font-size: 14px;
        font-weight: 500;
        color: rgba(0, 0, 0, 0.85);
        margin-bottom: 12px;
      }

      .tags-list {
        display: flex;
        flex-wrap: wrap;
        gap: 12px;
        padding: 4px 0;

        .tag-item {
          margin: 0;
          padding: 6px 16px;
          border-radius: 16px;
          font-size: 14px;
          border: 1px solid #d9d9d9;
          background: white;
          cursor: pointer;
          transition: all 0.3s;
          box-shadow: 0 2px 0 rgba(0, 0, 0, 0.02);

          &:hover {
            color: #1890ff;
            border-color: #1890ff;
          }

          &:global(.ant-tag-checkable-checked) {
            background: #e6f7ff;
            border-color: #1890ff;
            color: #1890ff;
            box-shadow: none;
          }
        }
      }
    }
  }

  .editor-container {
    .theme-selector {
      margin-bottom: 16px;
      display: flex;
      align-items: center;
      gap: 8px;

      span {
        color: rgba(0, 0, 0, 0.65);
      }
    }
  }

  :deep(.bytemd) {
    height: 600px;
  }

  :deep(.bytemd-fullscreen) {
    z-index: 1000 !important;
  }
}
</style>
